
<template>
  <!-- 外层表格包裹元素 -->
  <section class="ces-table-page">
    <!-- 表格组件: -->
    <section class="ces-table">
      <el-table
        v-loading="loading"
        ref="table"
        style="width: 100%"
        :data="tableData"
        :fit="isFit"
        :border="isBorder"
        :stripe="isStripe"
        :cell-style="{ padding: 5 }"
        :cell-class-name="tableOperationStyleFun"
        @select-all="selectAll"
        @selection-change="selectionChange"
      >
        <!-- 是否有前面的多选效果 -->
        <!-- width="40" 目前暂时不预设 多选效果表格头 的列宽为40 -->
        <el-table-column
          type="selection"
          align="center"
          v-if="isSelection"
          width="54"
        >
        </el-table-column>

        <!-- 是否显示前面的序号 -->
        <!-- width="40" 目前暂时不预设 序号表格头 的列宽为40 -->
        <el-table-column
          :label="indexLabel"
          v-if="isIndex"
          type="index"
          align="center"
          width="80"
        >
        </el-table-column>

        <!-- 表格的每一项：表格列数据 -->
        <!-- header-align="center" -->
        <template v-for="item in tableCols">
          <!-- 原先带有这个，目前删除 :render-header="renderHeader" -->
          <!--
            针对表格组件字符串初始化的问题：目前有两种合适的处理方案：
            1：利用该组件的formatter配置来手写格式化的方法。
            2：利用该组件自带的scope插槽写法来手动在template模板内实现文本格式化。

            可以参考的写法
            https://blog.csdn.net/William0326/article/details/102486374

            具体填写的参考值：
            :formatter="!!item.formatter ? item.formatter : null"
            :formatter="item.formatter() || (() => {})"
          -->
          <el-table-column
            v-if="!item.hidden"
            :prop="item.prop"
            :label="item.label"
            :key="item.prop"
            :sortable="item.isSortable || false"
            :fixed="item.fixed || null"
            :min-width="item.minWidth || ''"
            :width="item.width"
            :show-overflow-tooltip="overflow"
            :align="item.align"
            :formatter="!!item.formatter ? item.formatter() : () => {}"
          >
            <template #default="scope">
              <slot
                :name="item.slotname"
                :row="scope.row"
                :index="scope.$index"
              >
                {{ scope.row[item.prop] }}
              </slot>
            </template>
          </el-table-column>
        </template>
      </el-table>
    </section>
  </section>
</template>

<script>
export default {
  name: 'TableFrame',
  props: {
    // 1. 表格的尺寸大小 mini,medium,small
    size: { type: String, default: 'medium' },

    // 2. 是否需要带边框
    isBorder: { tyep: Boolean, default: true },

    // 3. 是否显示表格索引
    isIndex: { type: Boolean, default: false },
    indexLabel: { type: String, default: '序号' },

    // 4. 是否带斑马纹
    isStripe: { type: Boolean, default: false },

    // 5. 是否显示前面的多选效果
    isSelection: { type: Boolean, default: true },

    // 6. 是否显示分页
    // isPagination: { type: Boolean, default: false },

    // 7. 溢出隐藏
    overflow: { type: Boolean, default: true },

    //    分页数据
    // pagination: {
    //   type: Object,
    //   default: () => ({
    //     pageSizes: [10, 20, 50, 100],
    //     pageSize: 10,
    //     total: 200
    //   })
    // },

    // 7. 加载动画
    loading: { type: Boolean, default: false },

    // 8. 表格数据，一般都是发请求过来的
    tableData: { type: Array, default: () => [] },

    // 9. 表格列数据
    tableCols: { type: Array, default: () => [] },

    // 10. 表格上面的操作,比如导入，导出的操作
    isHandle: { type: Boolean, default: false },
    tableHandles: { type: Array, default: () => [] },

    // 11. 表格的每一列的宽度 是否自撑开？默认设置为是，自动自适应的宽度。
    isFit: { type: Boolean, default: true },
  },

  methods: {
    // 实现思路，当子组件发生改变时，发射同一个方法，在父组件调用的时候，不管怎么样，都可以接收到改变的值
    handleSizeChange(val) {
      console.log(`每页 ${val} 条`);
      this.$emit('updata', val);
    },

    handleCurrentChange(val) {
      console.log(`当前页: ${val}`);
      this.$emit('updata', val);
    },

    // 全选全部数据
    selectAll(val) {
      // console.log("in selectAll 表格子组件 全选表格 所选数据为：", val);
      this.$emit('selectAll', val);
    },

    // gxl 11-16 清空用户的选择
    clearSelection() {
      this.$refs.table.clearSelection();
    },

    /**
     * 选择项变化的行为监听函数
     * @param {Array} choicedItemList 被选择的表单项组成的数组。该形参是自带的默认自带的形参。
     * @author 阮中楠
     * @description 该函数来自于 el-table 组件自带的回调函数。此函数仅仅是二次封装。
     */
    selectionChange(choicedItemList) {
      // 监听完毕后，实时将所选的内容反馈给父组件。父组件需要一个变量接收该值。
      this.$emit('update:selectionChange', choicedItemList);
    },

    /**
     * 表格操作列的样式设置函数
     * @author 阮中楠
     * @description 用于解决表格右侧按钮的自带间距间隔的问题
     */
    tableOperationStyleFun({ row, column, rowIndex, columnIndex }) {
      // 几乎全部的组件在配置项都会设置 operation ，故此处写死并作出比较。
      if (column['property'] === 'operation') {
        return 'double-button-clear-style';
      }
      return '';
    },
  },
};
</script>

<style lang="scss" scoped>
// 总的页面
.ces-table-page {
  // 2021-10-16 gxl  目前通过统一设置表格组件的margin来控制
  margin: 20px 0;

  .el-table {
    /deep/ th {
      padding: 5px;
    }
    /deep/ td {
      padding: 5px;
    }

    // 表头文字不换行超过点点...展示
    /deep/ th.el-table__cell > .cell {
      white-space: pre !important;
      // background-color: red;
    }

    /*
      双按钮情形时 清空系统自带样式
      表格右侧的操作栏在业务上可能设计成两个按钮，而这两个按钮会被使用到element自带的样式，影响了表格列的显示。
      现在需要在表格组件内统一清空。
    */
    /deep/ .double-button-clear-style {
      .el-button + .el-button {
        margin-left: 0px;
      }
    }

    // 排序按钮容器大小调整
    /deep/ .caret-wrapper {
      // 修改预设的34px，这个值导致表格表头太高了，显得间距很大。
      height: 16px;
    }

    // 表格表头排序按键的控制，正序排序按钮
    /deep/ .sort-caret.ascending {
      top: -6px;
    }

    // 表格表头排序按键的控制，倒序排序按钮
    /deep/ .sort-caret.descending {
      bottom: -3px;
    }
  }
}
</style>
